package com.zenchn.schedule;

import com.zenchn.model.TSysScheduleTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 定时任务调度执行实现类
 *
 * @author panbingqi
 * @date 2021-06-01
 */
@Service
public class SchedulerService {
    private static final Logger logger = LoggerFactory.getLogger(SchedulerService.class);


    private static Map<String, TaskScheduler> taskSchedulerMap = new HashMap<>(16);


    @Resource
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    /**
     * 根据key获取定时任务实例
     *
     * @param scheduleId
     * @return
     */
    public  TaskScheduler getTaskSchedulerMap(String scheduleId) {
        return taskSchedulerMap.get(scheduleId);
    }


    /***
     * 启用定时任务
     * @param scheduleTask
     */
    public   void  enableSchedule(TSysScheduleTask scheduleTask){
        try {
            String cron = scheduleTask.getCron();
            Long fixedDelay=scheduleTask.getFixedDelay();

            TaskScheduler taskScheduler = getTaskScheduler(scheduleTask);
            if (null!=taskScheduler){
                taskScheduler.start(cron,fixedDelay);
                logger.info("开启[{}]任务成功！",scheduleTask.getScheduleName());
            }else{
                logger.error("开启[{}]任务异常，无法找到该任务体",scheduleTask.getScheduleName());
            }

            taskSchedulerMap.put(scheduleTask.getScheduleId(), taskScheduler);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("开启[{}]任务失败，原因:{}",scheduleTask.getScheduleName(),e.getMessage());
        }

    }

    /**
     * 停用定时任务
     * @param scheduleTask
     */
    public   void  disableSchedule(TSysScheduleTask scheduleTask) {
        try {

            TaskScheduler taskScheduler = getTaskScheduler(scheduleTask);
            if (null!=taskScheduler){
                taskScheduler.stop();
                taskSchedulerMap.remove(scheduleTask.getScheduleId());
                logger.info("停用[{}]任务成功！",scheduleTask.getScheduleName());
            }else{
                logger.error("停用[{}]任务异常，无法找到该任务体",scheduleTask.getScheduleName());
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("停用[{}]任务失败，原因:{}",scheduleTask.getScheduleName(),e.getMessage());
        }
    }


    private   TaskScheduler  getTaskScheduler(TSysScheduleTask scheduleTask) throws Exception{
        String cron = scheduleTask.getCron();
        String schedulerClass = scheduleTask.getSchedulerClass();
        Long fixedDelay=scheduleTask.getFixedDelay();
        Runnable runnable = (Runnable) Class.forName(schedulerClass).newInstance();
        TaskScheduler taskScheduler = getTaskSchedulerMap(scheduleTask.getScheduleId());
        if (taskScheduler == null) {
            if (null!=cron && !"".equals(cron)) {
                taskScheduler = SchedulerFutureFactory.createTaskScheduler(scheduleTask.getScheduleId(), runnable, cron,
                        threadPoolTaskScheduler);
            }
            if (null!=fixedDelay) {
                taskScheduler = SchedulerFutureFactory.createTaskScheduler(scheduleTask.getScheduleId(), runnable, fixedDelay,
                        threadPoolTaskScheduler);
            }
        }
        return taskScheduler;
    }




    /**
     * 立即执行调度任务
     * @param scheduleTask
     */
    public   void  runningScheduleTask(TSysScheduleTask scheduleTask) {
        try {
            String schedulerClass = scheduleTask.getSchedulerClass();
            Runnable runnable = (Runnable) Class.forName(schedulerClass).newInstance();
            threadPoolTaskScheduler.execute(runnable);

            logger.info("立即执行[{}]任务成功！",scheduleTask.getScheduleName());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("立即执行[{}]任务失败，原因:{}",scheduleTask.getScheduleName(),e.getMessage());
        }
    }
}
